package com.gzucm.Scholarship.config.security;

import com.gzucm.Scholarship.annotation.AuthorityCheck;
import com.gzucm.Scholarship.common.enums.UserType;
import com.gzucm.Scholarship.exception.AuthorityException;
import com.gzucm.Scholarship.service.CurrentService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Aspect
@Component
public class AuthorityCheckAop {

    @Autowired
    private CurrentService currentService;

    @Around("@annotation(authorityCheck) || @within(authorityCheck)")
    public Object checkRight(ProceedingJoinPoint jP, AuthorityCheck authorityCheck) throws Throwable {
        MethodSignature sign = (MethodSignature) jP.getSignature();
        Method method = sign.getMethod();
        //假如类和方法同时存在，方法上的优先
        AuthorityCheck temp = method.getAnnotation(AuthorityCheck.class);
        authorityCheck = Objects.isNull(temp) ? authorityCheck : temp;

        boolean require = authorityCheck.require();
        if (Objects.equals(require, false)) {//不需要
            return jP.proceed();
        }
        List<UserType> valueList = Arrays.asList(authorityCheck.value());
        if (valueList.isEmpty()) {//没指定
            return jP.proceed();
        }

        UserType me = UserType.get(currentService.getCurrentUser().getType());
        if (valueList.contains(me)) {
            return jP.proceed();
        } else {
            throw new AuthorityException("不允许访问此接口");
        }
    }

}
